#include "CTimer.h"
#include <assert.h>
#include "os.h"

namespace ldx
{
	namespace device
	{
		float CTimer::msCyclesPerSecond = 0.f;
		double CTimer::msSystemCurrentTime = 0.;
		double CTimer::msSystemLastTime = 0.;
		float CTimer::msSystemdeltaTime = 0.f;
		bool CTimer::firstTimeNew = false;
		double CTimer::getSystemRealTime()
		{
			return os::Timer::getRealTime();
		}

		void CTimer::initSystemTimer()
		{
			unsigned long f = (unsigned long)os::Timer::getFrequency();

			msCyclesPerSecond = static_cast<float>(f);
			assert(f != 0&&"Timer::initSystemTimer didn't call glfwInit()");
			std::cout << "Timer frequency:" << f << std::endl;
			msSystemCurrentTime = getSystemRealTime();
			msSystemLastTime = msSystemCurrentTime;
			msSystemdeltaTime = 0.0f;
		}

		void CTimer::updateSystemTimer()
		{
			msSystemLastTime = msSystemCurrentTime;
			msSystemCurrentTime = getSystemRealTime();
			msSystemdeltaTime = static_cast<float>(msSystemCurrentTime - msSystemLastTime);
			// static_cast<float>(msSystemCurrentTime - msSystemLastTime)/msCyclesPerSecond;
		}

		float CTimer::getSystemDeltaTime()
		{
			return msSystemdeltaTime;
		}


		void CTimer::sleepSystem(double sleepTime)
		{
			//double endTime = getSystemRealTime() + sleepTime;
			//double nowTime = 0.0;
			Sleep(static_cast<DWORD>(sleepTime*1000.0));
			//do
			//{
			//	nowTime = getSystemRealTime();
			//} while (endTime >= nowTime);
		}

		CTimer::CTimer(float startTimeSeconds)
			:mTimeCycles(secondsToCycles(startTimeSeconds)),
			mTimeScale(1.f),
			mIsPasued(false)
		{
			if (firstTimeNew == false)
			{
				os::Timer::initTimer();
				initSystemTimer();
				firstTimeNew = true;
			}
		}

		//! destructor
		CTimer::~CTimer()
		{

		}

		//! Return time ticks of time cycle.
		unsigned long CTimer::getTimeCycles() const
		{
			return mTimeCycles;
		}

		//Cacl this timer - other timer,in second
		float CTimer::caclDetaSeconds(const CTimer& other)
		{
			unsigned long dt = mTimeCycles - other.mTimeCycles;
			return cyclesToSeconds(dt);
		}

		//! Advances the  time,update
		void CTimer::update(float dtRealDeltaSeconds)
		{
			if (!mIsPasued)
			{
				float deltatime = dtRealDeltaSeconds*mTimeScale;
				mTimeCycles += secondsToCycles(deltatime);
				mDeltaTime = deltatime;
			}
		}

		float CTimer::getDeltaTime() const
		{
			return mDeltaTime;
		}

		//! Stops the  timer.
		void CTimer::setPaused()
		{
			mIsPasued = true;
		}

		//! Starts the  timer.
		void CTimer::setStart()
		{
			mIsPasued = false;
		}

		//! Sets the speed of the timer
		/** The speed is the factor with which the time is running faster or
		slower then the real system time. */
		void CTimer::setSpeed(float speed)
		{
			mTimeScale = speed;
		}

		//! Returns current speed of the timer
		/** The speed is the factor with which the time is running faster or
		slower then the real system time. */
		float CTimer::getSpeed() const
		{
			return mTimeScale;
		}

		//! Returns if the  timer is currently stopped
		bool CTimer::isStopped() const
		{
			return mIsPasued;
		}

		void CTimer::singleStep(float timeEachFrame)
		{
			if (mIsPasued)
			{
				unsigned long dtScaledCycles = secondsToCycles(
					timeEachFrame*mTimeScale);
				mTimeCycles += dtScaledCycles;
			}
		}


		float CTimer::getCyclesFrequency()const
		{
			return msCyclesPerSecond;
		}
	}
}